#include "qdrivebar.h"
#include "ui_qdrivebar.h"

#include "../../lib/corelib/stylehelper.h"
#include "../../lib/corelib/qactiontoolbar.h"
#include "../../lib/shared/qproject.h"
#include "../../lib/shared/qdriveplugininterface.h"
#include "../../lib/shared/qdriveattribute.h"
#include "../../lib/shared/qabstractdrive.h"

#include "qdrivelistdialog.h"
#include "qdrivenamedialog.h"

#include <QStringListModel>
#include <QStyleOptionHeader>
#include <QMouseEvent>
#include <QScrollBar>
#include <QPainter>
#include <QLinearGradient>
#include <QAction>

#include <QStyleOptionHeader>

static void drawSeparator(QPainter *p,QPoint top,QPoint bottom)
{
    QLinearGradient grad(top,bottom);

    grad.setColorAt(0,QColor(255,255,255,20));
    grad.setColorAt(0.4,QColor(255,255,255,60));
    grad.setColorAt(0.7,QColor(255,255,255,50));
    grad.setColorAt(1,QColor(255,255,255,40));
    p->setPen(QPen(grad,0));
    p->drawLine(top,bottom);
    grad.setColorAt(0,QColor(0,0,0,30));
    grad.setColorAt(0.4,QColor(0,0,0,70));
    grad.setColorAt(0.7,QColor(0,0,0,70));
    grad.setColorAt(1,QColor(0,0,0,40));
    p->setPen(QPen(grad,0));
    p->drawLine(top-QPoint(1,0),bottom-QPoint(1,0));
}

void DriveDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    QStyleOptionViewItemV3 opt=option;
    opt.state &=~ QStyle::State_HasFocus;
    opt.state &=~ QStyle::State_Selected;
    opt.displayAlignment=Qt::AlignCenter;


    if(m_bar->current()==index.column())
    {
        QLinearGradient grad(opt.rect.topLeft(),opt.rect.bottomLeft());
        grad.setColorAt(0,QColor(247,247,247));
        grad.setColorAt(1,QColor(205,205,205));
        QRect re=opt.rect.adjusted(0,0,-2,-2);
        painter->fillRect(re,grad);
        painter->setPen(StyleHelper::borderColor());
        painter->drawLine(re.bottomLeft(),re.bottomRight());
    }
    QItemDelegate::paint(painter,opt,index);
    if(index.model()->columnCount(QModelIndex())!=index.column()+1)
    {
        drawSeparator(painter,opt.rect.topRight(),opt.rect.bottomRight());
    }
}

QWidget *DriveDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    return NULL;
}

QSize DriveDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    QSize sz;
    sz.setHeight(27);
    sz.setWidth(option.fontMetrics.width(index.data(Qt::DisplayRole).toString()));
    return sz;
}


DriveHeadView::DriveHeadView(QWidget *parent):
    QTreeWidget(parent)
{
    this->setFrameStyle(QFrame::NoFrame);
    this->setAutoFillBackground(false);
    this->viewport()->setAutoFillBackground(false);
    this->setFixedHeight(27);
    this->header()->setVisible(false);
    this->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    this->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    this->setRootIsDecorated(false);
}


QDriveBar::QDriveBar(QWidget *parent) :
    StyledBar(parent),
    ui(new Ui::QDriveBar),
    m_headView(new DriveHeadView(this)),
    m_toolBar(new QActionToolBar),
    m_current(-1)
{
    ui->setupUi(this);

    ui->horizontalLayout->insertWidget(0,m_headView,1);
    ui->horizontalLayout->addWidget(m_toolBar);
    m_headView->setItemDelegate(new DriveDelegate(this));

    connect(ui->leftPane,SIGNAL(clicked()),this,SLOT(prev()));
    connect(ui->rightPane,SIGNAL(clicked()),this,SLOT(next()));
    connect(m_headView,SIGNAL(clicked(QModelIndex)),this,SLOT(sectionClicked(QModelIndex)));

    QList<QAction*> list;

    QAction *ac;

    ac=new QAction(this);
    ac->setSeparator(true);
    list.append(ac);

    ac=new QAction(QIcon(":/images/append.png"),"Add New Driver",this);
    list.append(ac);
    connect(ac,SIGNAL(triggered()),this,SLOT(addDrive()));
    ac=new QAction(QIcon(":/images/remove.png"),"Remove Driver",this);
    connect(ac,SIGNAL(triggered()),this,SIGNAL(remove()));
    list.append(ac);

    ac=new QAction(this);
    ac->setSeparator(true);
    list.append(ac);

    ac=new QAction(QIcon(":/images/plus.png"),"Add Value",this);
    connect(ac,SIGNAL(triggered()),this,SIGNAL(addValue()));
    list.append(ac);
    ac=new QAction(QIcon(":/images/minus.png"),"Remove Value",this);
    connect(ac,SIGNAL(triggered()),this,SIGNAL(removeSelectValue()));
    list.append(ac);

    m_toolBar->addButtonActions(list);

    m_item=new QTreeWidgetItem(m_headView);
    m_headView->setColumnCount(1);
}

QDriveBar::~QDriveBar()
{
    delete ui;
}

void QDriveBar::prev()
{
    if(m_headView->columnCount()>1)
    {
        int index=m_current-1;
        if(index<0)
        {
            emit select(m_headView->columnCount()-2);
        }
        else
        {

            emit select(index);
        }
    }
}

void QDriveBar::next()
{
    if(m_headView->columnCount()>1)
    {
        int index=m_current+1;
        if(index>m_headView->columnCount()-2)
        {
            emit select(0);
        }
        else
        {

            emit select(index);
        }
    }
}

void QDriveBar::sectionClicked(const QModelIndex &index)
{
    if(index.column()!=m_headView->columnCount()-1)
    {
        emit select(index.column());
    }
}

void QDriveBar::setSelect(int index)
{
    if(m_current!=-1)
    {
        m_headView->update(m_headView->model()->index(0,m_current));
    }
    m_current=index;

    if(m_current!=-1)
    {
        m_headView->update(m_headView->model()->index(0,m_current));
        m_headView->setCurrentIndex(m_headView->model()->index(0,m_current));
    }
}

int QDriveBar::current()
{
    return m_current;
}

void QDriveBar::addItem(const QString &text)
{
    int index=m_headView->columnCount();
    m_headView->setColumnCount(index+1);

    m_item->setText(index-1,text);
    QFontMetrics fm(m_headView->font());
    int w=fm.width(text)+20;
    if(w<100)
    {
        w=100;
    }
    m_headView->setColumnWidth(index-1,w);
    m_item->setToolTip(index-1,text);
    emit select(index-1);
}

void QDriveBar::removeItem(int index)
{
    int c=m_headView->columnCount();
    QString str;
    for(int i=index;i<c-1;i++)
    {
        str=m_item->text(i+1);
        m_item->setText(i,str);
        QFontMetrics fm(m_headView->font());
        int w=fm.width(str)+20;
        if(w<100)
        {
            w=100;
        }
        m_headView->setColumnWidth(i,w);
        m_item->setToolTip(i,str);
    }
    m_headView->setColumnCount(c-1);
    if(m_current>=m_headView->columnCount()-2)
    {
        emit select(m_headView->columnCount()-2);
    }
}

void QDriveBar::clear()
{
    m_headView->setColumnCount(1);
    m_item->setText(0,"");
    m_item->setToolTip(0,"");
}

void QDriveBar::addDrive()
{
    QDriveListDialog dlg(this);


    dlg.exec();
    QString select=dlg.getSelect();

    if(select!="")
    {
        QDriveNameDialog nd(this);
        nd.exec();
        QString name=nd.getName();
        if(name!="")
        {
            tagDriveInfo info;
            info.m_name=name;
            info.m_path=select;
            QMap<QString,tagDrivePluginInfo> plugins=QProject::project()->drivePlugins();
            QString path=select.split(":").first();
            foreach(tagDrivePluginInfo in,plugins)
            {

                if(path==in.m_path)
                {
                    info.m_drive=in.m_drivePlugin->createDrive(select.split(":").at(1));
                    if(info.m_drive==NULL)
                    {
                        return;
                    }
                    info.m_drive->attribute("Name")->setValue(info.m_name);
                    QProject::project()->insertDrive(-1,info);
                    emit addWidget(m_headView->columnCount()-1);
                    addItem(info.m_name);

                    break;
                }
            }


        }
    }
}
